---------------------------------------------------------------
-- @Description：         agent handler
---------------------------------------------------------------
local skynet = require "skynet"
local log = require "sky_log"
local socket = require "skynet.socket"
local packetbase = require "lua_packetbase"
local robot_logic = require "robot_logic"
local cc = require "sky_call"
local CMD = require "cmds"
local serpent = require "serpent"
require "def"

local M = {}

--============================= Local Function =============================--
local function send_msg(fd, msg, size)
    --[[
    log.info("++++++++++++++++++++++++++++++++")
    log.info("send_msg fd=", fd)
    log.info("send_msg msg=", msg)
    log.info("send_msg size=", size)
    log.info("++++++++++++++++++++++++++++++++")
    --]]

    socket.write(fd, msg, size)
end

local function test_memdb(robot, fd)
    local pack = packetbase.create_writebase()
    pack:write_begin(0x1004, 1, 2)
    pack:write_int(215698)
    pack:write_end()
    local msg, size = pack:return_buf()
    send_msg(fd, msg, size)
end

local function test_echo(robot, fd)
    local pack = packetbase.create_writebase()
    pack:write_begin(0x7002)
    pack:write_end()
    local msg, size = pack:return_buf()
    send_msg(fd, msg, size)
end

local function check_game_type(robot_game_type, game_type_t)
    for _, v in pairs(game_type_t or {}) do
        if tonumber(robot_game_type)==tonumber(v) then
            return true
        end
    end

    return false
end

local function set_login_info(robot)
    --log.info("set_login_info robot=", robot)
    --local set_data = "mid:0,mtkey:abcdefghabcdefghabcdefghabcdefgh,tid:0,mvip:1,mstatus:0,sid:0,unid:0,bankruptLine:10000,mttsig:0,lvl:10,ss:9999,svid:18460,solevel:0,role:robot,0"
    
    local set_data = ''
    for k, v in pairs(LOGIN_INFO) do
        set_data = set_data ..k..":"..v..","
    end

    local svid_str = ''
    local solevel_str = ''
    if robot.config_info.svid then
        svid_str = "svid:"..robot.config_info.svid..","
    end
    if robot.config_info.solevel then 
        solevel_str = "svid:"..robot.config_info.solevel..","
    end
    set_data = set_data..svid_str..solevel_str.."role:robot,"

    cc.call_memcache("set_record", "memcache_uid", tonumber(robot.platid), tonumber(robot.db_info.id), set_data)

    local v = cc.call_memcache("get_exp", "memcache_exp",  tonumber(robot.platid), tonumber(robot.db_info.id))
    if not v then
        local index = math.random(1000, 3000)
        local set_exp_data = "exp"..index
        cc.call_memcache("set_record", "memcache_exp", tonumber(robot.platid), tonumber(robot.db_info.id), set_exp_data)
    end
end

--============================= Actions =============================--
local function add_robot_again(platid, tid)
    local msg = {
        platid = tonumber(platid),
        tid = tonumber(tid),
    }
    skynet.send(".robot_manager", "lua", "add", msg)

    --log.info("add_robot_again add_info ", msg)
end

local function on_login_error(robot, fd, packet)
  
    local err_t = {}
    err_t.error_type = packet:read_int()
    err_t.ts = packet:read_int64()
    err_t.tid = packet:read_int()
    err_t.ts2 = packet:read_int64() 
    log.warning("on_login_error robot= ", tonumber(robot.db_info.id).."  error_type="..err_t.error_type)

    local platid = robot.config_info.platid
    local tid = robot.config_info.tid
    local robot_table_type = tonumber(robot.config_info.table_type)

    skynet.send(skynet.self(), "lua", "disconnect_server")

    --登录错误再重新进一个
    if robot_table_type==TABLE_TYPE.TARNEEB then
        if err_t.error_type==13 then
            add_robot_again(platid, tid)
        end
    elseif robot_table_type==TABLE_TYPE.TEXAS_ROYAL then
        if err_t.error_type==1 then
            add_robot_again(platid, tid)
        end
    end
end

local function on_sit_failed(robot, fd, packet)
    local err_t = {}
    err_t.error_type = packet:read_int()
    log.warning("on_sit_failed robot=", (robot.user_id) .."  error_type="..err_t.error_type)

    local platid = tonumber(robot.platid)
    local tid = tonumber(robot.tid)
    local robot_table_type = tonumber(robot.table_type)

    skynet.send(skynet.self(), "lua", "disconnect_server")

    --金币不足时再重新进一个机器人
    if robot_table_type==TABLE_TYPE.TARNEEB then
        if err_t.error_type==12 then
            add_robot_again(platid, tid)
        end
    end
end

local function on_stand(robot, fd, packet)
    local seat_id = packet:read_int()

    skynet.send(skynet.self(), "lua", "disconnect_server")
end

--德州和塔尼布消息不通用，所以分文件处理，设计之初是想把通用的登录，登出，
--坐下，站起放入该文件内实现。后续若有游戏消息通用时就在本文件实现
local actions = {
    --德州
    [CMD.SERVER_COMMAND_LOGIN_ERR] = on_login_error,
    [CMD.SERVER_COMMAND_SIT_FAILED] = on_sit_failed,
    [CMD.SERVER_BROADCAST_USER_STAND] = on_stand,
    --塔尼布
    [CMD.SERVER_COMMAND_TARNEEB_LOGIN_ERR] = on_login_error,
    [CMD.SERVER_COMMAND_TARNEEB_SIT_FAILED] = on_sit_failed,
    [CMD.SERVER_TARNEEB_BROADCAST_USER_STAND] = on_stand,
}

--============================= MSG =============================--
function M.do_timer()
    robot_logic["do_timer"]()
end

function M.do_login(robot, fd)
    --机器人生成时改种子就OK
    math.randomseed(tostring(os.time() + (tonumber(robot.db_info.id) or 0)):reverse():sub(1, 7))

    set_login_info(robot)

    local robot_game_type = tonumber(robot.config_info.table_type)
    ---[[
    if check_game_type(robot_game_type, robot_logic.GAME_TYPE)==false then
        log.error("robot_game_type error! robot_game_type=", robot_game_type)
        skynet.send(skynet.self(), "lua", "disconnect_server")
        return
    end
    --]]

    local f = M.login_game
    if f then
        f(robot, fd)
    else
        robot_logic.login_game(robot, fd)
    end
end

function M.do_logout(robot, fd)
    local f = M.logout_game
    if f then
        f(robot, fd)
    else
        robot_logic.logout_game(robot, fd)
    end
end

--[[
--过滤的cmd
IGNORE_CMDS = {
    0x4236,     --none
    0x423C,     --none
    0x4233,     --SERVER_TARNEEB_BROADCAST_USER_MANDATE             广播用户托管
    0x4234,     --SERVER_TARNEEB_BROADCAST_USER_CANCEL_MANDATE      广播用户取消托管
    0x311C,     --SERVER_COMMAND_UPDATE_USERINFO
    0x423B,     --SERVER_TARNEEB_BROADCAST_USER_CONTINUE            轮结束广播玩家是否继续游戏
    0x4237,     --["SERVER_TARNEEB_BROADCAST_ROBOT_MANDATE"]        广播机器人托管
}
--]]
function M.dispatch_msg(robot, fd, msg, sz)
    --log.info("agent dispatch_msg sz=", sz)

	local packet = packetbase.create_readbase()
	local copy_flag = packet:copy(msg, sz)
	--log.info("agent dispatch_msg copy_flag=", copy_flag)

	local decrypt_size = packet:decrypt_buffer()
	--log.info("agent dispatch_msg decrypt_size=", decrypt_size)

	local cmd_type = packet:get_cmd_type()
	--log.debug("agent dispatch_msg receive cmd=", string.format("%04X", cmd_type))
    --[[
    for _, v in pairs(IGNORE_CMDS) do
        if cmd_type==v then 
            return
        end
    end
    --]]

    local f
    if actions[tonumber(cmd_type)] then 
        f = actions[tonumber(cmd_type)]
    else
        f = robot_logic.actions[tonumber(cmd_type)]
    end

    if f then
        local ret = f(robot.game_info or robot, fd, packet)
    else
        --log.error("undenfine cmd: ", cmd_type)
    end
end

return M